<?php

namespace app\common\model\search;

use app\common\model\CollectCase as CaseModel;
use app\common\model\DiseaseType as DiseaseTypeModel;
use catcher\exceptions\FailedException;

trait PatientInfoSearch
{
    //==========================================================================================

    /**
     * 筛选条件
     */

    //类型：1门诊，2住院，3出院
    public function searchTypeAttr($query, $value, $data)
    {
        $condition = [];
        if (!empty($data["outhospitalDate"])) {
            $dateArr = array_unique($data["outhospitalDate"]);
            if(count($dateArr) ==2) {
                parse_str($data["outhospitalDate"], $outHospitalDateArr);
                $condition[] = ['$gte' => ['$$item.outhospitalDate', $outHospitalDateArr[0]]];
                $condition[] = ['$lte' => ['$$item.outhospitalDate', $outHospitalDateArr[1]]];
            }
        }

        if (!empty($data["bz"])) {
            $condition[] = ['$in' => ['$$item.bingzhong_id', $data["bz"]]];
        }

        switch ($value) {
            case 0:
                $res = $query->whereIn('is_in_hospital', [1, 2])->whereOr($this->getUserJurisdiction(2))->whereOr($this->getUserJurisdiction(3))->field(['id', 'patientId', 'patient_id', 'name', 'sex', 'inage', 'birthdate', 'presentTelphone', 'liveStatus', 'inList', 'follow_node', 'is_in_hospital', 'bz', 'medicalRecordsNo', 'bzItem' => [
                    '$filter' => [
                        'input' => '$bz.bingzhongArr',
                        'as' => 'item',
                        'cond' => [
                            '$and' => [
                                $condition
                            ]
                        ]
                    ]
                ]]);
                break;
            case 1:
                $res = $query->where($this->getUserJurisdiction(1))->field(['id','patientId','name','sex','inage','birthdate','presentTelphone','outList','liveStatus','follow_node','bz', 'medicalRecordsNo','bzItem' => [
                    '$filter' => [
                        'input' => '$bz.bingzhongArr',
                        'as' => 'item',
                        'cond' => [
                            '$and' => [
                                $condition
                            ]
                        ]
                    ]
                ]]);
                break;
            case 2:
                $res = $query->where('is_in_hospital', 1)->where($this->getUserJurisdiction(2))->field(['id','patientId','patient_id','name','sex','inage','birthdate','presentTelphone','inList','liveStatus','follow_node','bz', 'medicalRecordsNo', 'bzItem' => [
                    '$filter' => [
                        'input' => '$bz.bingzhongArr',
                        'as' => 'item',
                        'cond' => [
                            '$and' => [
                                $condition
                            ]
                        ]
                    ]
                ]]);
                break;
            case 3:
                $res = $query->where('is_in_hospital', 2)->where($this->getUserJurisdiction(3))->field(['id', 'patientId', 'patient_id', 'name', 'sex', 'inage', 'birthdate', 'presentTelphone', 'liveStatus', 'hoList', 'follow_node', 'bz', 'medicalRecordsNo', 'bzItem' => [
                    '$filter' => [
                        'input' => '$bz.bingzhongArr',
                        'as' => 'item',
                        'cond' => [
                            '$and' => [
                                $condition
                            ]
                        ]
                    ]
                ]]);
                break;
            case 4:
                $res = $query->where('sourceType', 2)->field('id,patientId,name,sex,presentTelphone,created_ymd,idno');
                break;
            default:
                throw new FailedException("类型错误");
        }
        return $res;
    }

    //姓名
    public function searchNameAttr($query, $value, $data)
    {
        return $query->where('name', '=', ['$regex' => '^' . trim($value)]);

    }

    //门诊号
    public function searchClinicNoAttr($query, $value, $data)
    {
        return $query->where('outList.clinicNo', (int)trim($value));
    }

    //联系方式
    public function searchMobileAttr($query, $value, $data)
    {
        return $query->where('presentTelphone', trim($value));
    }

    //就诊科室
    public function searchDeptNameAttr($query, $value, $data)
    {
        return $query->where('outList.deptName', '=', ['$regex' => '^' . trim($value)]);
    }

    //主诊医生
    public function searchAttendingDoctorNameAttr($query, $value, $data)
    {
        return $query->where('outList.attendingDoctorName', '=', ['$regex' => '^' . $value]);
    }

    //疾病诊断
    public function searchDiagnosisAttr($query, $value, $data)
    {
        return $query->where('inList.diagnose', '=', ['$regex' => '^' . trim($value)])
            ->whereOr('outList.diseaseList.disease.diseaseName', '=', ['$regex' => '^' . trim($value)]);
    }

    //住院疾病诊断编码
    public function searchDiseaseNoAttr($query, $value, $data)
    {
        return $query->where('inList.diseaseNo', '=', ['$regex' => '^' . trim($value)]);
    }

    //病种
    public function searchDiseaseTypeAttr($query, $value, $data)
    {
        $disease = (new DiseaseTypeModel())->getConditionOne([['name', '=', trim($value)]], 'diseaseList');
        if (!empty($disease['diseaseList'])) {
            return $query->whereIn('inList.diseaseNo', $disease['diseaseList']);
        }

    }

    //住院号
    public function searchInhospitalNoAttr($query, $value, $data)
    {

        switch ($data['type']) {
            case 3:
                $res = $query->where('hoList.inhospitalNo', trim($value));
                break;
            case 2:
            default:
                $res = $query->where('inList.inhospitalNo', trim($value));
                break;
        }
        return $res;
    }

    //出院科室
    public function searchOuthospitalDeptAttr($query, $value, $data)
    {

        return $query->where('hoList.outhospitalDept', '=', ['$regex' => '^' . strip_tags(trim($value))]);
    }

    //出院病区
    public function searchOuthospitalWardAttr($query, $value, $data)
    {
        return $query->where('hoList.outhospitalWard', '=', ['$regex' => '^' . trim($value)]);
    }

    //疾病、入院诊断
    public function searchDiagnoseAttr($query, $value, $data)
    {
        switch ($data['type']) {
            case 1:
                $res = $query->where('outList.diseaseName', '=', ['$regex' => trim($value)]);
                break;
            case 3:
                $res = $query->where('hoList.diagnose', '=', ['$regex' => trim($value)]);
                break;
            case 2:
            default:
                $res = $query->where('inList.diagnose', '=', ['$regex' => trim($value)]);
                break;
        }
        return $res;
    }

    //入院日期标识 3 全部，1 首次， 2 末次
    public function searchInhospitalDateTypeAttr($query, $value, $data){}
    //出院日期标识 3 全部，1 首次， 2 末次
    public function searchOuthospitalDateTypeAttr($query, $value, $data){}
    //门诊日期标识 3 全部，1 首次， 2 末次
    public function searchVisitTimeTypeAttr($query, $value, $data){}

    //门诊时间
    public function searchVisitTimeAttr($query, $value, $data)
    {
        $date = $value;
        $where = [];

        switch ($data['visitTimeType']) {
            case 1:
                if (isset($date[0]) && !empty($date[0])) {

                    $where[] = ['calc_date_node.first_visit_time', '>=', date("Y-m-d", strtotime($date[0]))];
                }
                if (isset($date[1]) && !empty($date[1])) {

                    $where[] = ['calc_date_node.first_visit_time', '<=', date("Y-m-d", strtotime($date[1]))];
                }
                break;
            case 2:
                if (isset($date[0]) && !empty($date[0])) {

                    $where[] = ['calc_date_node.last_visit_time', '>=', date("Y-m-d", strtotime($date[0]))];
                }
                if (isset($date[1]) && !empty($date[1])) {

                    $where[] = ['calc_date_node.last_visit_time', '<=', date("Y-m-d", strtotime($date[1]))];
                }
                break;
            case 3:
                if (!empty($date[0]) || !empty($date[1])) {
                    if (((isset($date[0]) && !empty($date[0])) && (isset($date[1]) && !empty($date[1]))) && $date[0] == $date[1]) {
                        $where[] = ['calc_date_node.visit_time_arr', '=', date("Y-m-d", strtotime($date[0]))];

                    }else{

                        if (isset($date[0]) && !empty($date[0])) {

                            $where[] = ['calc_date_node.visit_time_arr', '>=', date("Y-m-d", strtotime($date[0]))];
                        }
                        if (isset($date[1]) && !empty($date[1])) {

                            $where[] = ['calc_date_node.visit_time_arr', '<=', date("Y-m-d", strtotime($date[1]))];
                        }
                    }
                }

                break;
            default:
                break;
        }
        return $query->where($where);
    }

    //入院日期
    public function searchInhospitalDateAttr($query, $value, $data)
    {
        //parse_str($value, $date);
        $date = $value;
        $where = [];

        switch ($data['inhospitalDateType']) {
            case 1:
                if (isset($date[0]) && !empty($date[0])) {

                    $where[] = ['calc_date_node.first_in_hospital_date', '>=', date("Y-m-d", strtotime($date[0]))];
                }
                if (isset($date[1]) && !empty($date[1])) {

                    $where[] = ['calc_date_node.first_in_hospital_date', '<=', date("Y-m-d", strtotime($date[1]))];
                }
                break;
            case 2:
                if (isset($date[0]) && !empty($date[0])) {

                    $where[] = ['calc_date_node.last_in_hospital_date', '>=', date("Y-m-d", strtotime($date[0]))];
                }
                if (isset($date[1]) && !empty($date[1])) {

                    $where[] = ['calc_date_node.last_in_hospital_date', '<=', date("Y-m-d", strtotime($date[1]))];
                }
                break;
            case 3:
                if (!empty($date[0]) || !empty($date[1])) {
                    if (((isset($date[0]) && !empty($date[0])) && (isset($date[1]) && !empty($date[1]))) && $date[0] == $date[1]) {
                        $where[] = ['calc_date_node.inhospitalDateArr', '=', date("Y-m-d", strtotime($date[0]))];

                    }else{
                        if (isset($date[0]) && !empty($date[0])) {

                            $where[] = ['calc_date_node.inhospitalDateArr', '>=', date("Y-m-d", strtotime($date[0]))];
                        }
                        if (isset($date[1]) && !empty($date[1])) {

                            $where[] = ['calc_date_node.inhospitalDateArr', '<=', date("Y-m-d", strtotime($date[1]))];
                        }
                    }
                }

                break;
            default:
                break;
        }
        return $query->where($where);
    }

    //出院日期
    public function searchOuthospitalDateAttr($query, $value, $data)
    {
        //parse_str($value, $date);
        $date = $value;
        $where = [];

        switch ($data['outhospitalDateType']) {
            case 1:
                if (isset($date[0]) && !empty($date[0])) {

                    $where[] = ['calc_date_node.first_out_hospital_date', '>=', date("Y-m-d", strtotime($date[0]))];
                }
                if (isset($date[1]) && !empty($date[1])) {
                    $where[] = ['calc_date_node.first_out_hospital_date', '<=', date("Y-m-d", strtotime($date[1]))];
                }
                break;
            case 2:
                if (isset($date[0]) && !empty($date[0])) {

                    $where[] = ['calc_date_node.last_out_hospital_date', '>=', date("Y-m-d", strtotime($date[0]))];
                }
                if (isset($date[1]) && !empty($date[1])) {

                    $where[] = ['calc_date_node.last_out_hospital_date', '<=', date("Y-m-d", strtotime($date[1]))];
                }
                break;
            case 3:
                if (!empty($date[0]) || !empty($date[1])) {
                    if (((isset($date[0]) && !empty($date[0])) && (isset($date[1]) && !empty($date[1]))) && $date[0] == $date[1]) {
                        $where[] = ['calc_date_node.outhospitalDateArr', '=', date("Y-m-d", strtotime($date[0]))];

                    }else{
                        if (isset($date[0]) && !empty($date[0])) {

                            $where[] = ['calc_date_node.outhospitalDateArr', '>=', date("Y-m-d", strtotime($date[0]))];
                        }
                        if (isset($date[1]) && !empty($date[1])) {

                            $where[] = ['calc_date_node.outhospitalDateArr', '<=', date("Y-m-d", strtotime($date[1]))];
                        }
                    }
                }

                break;
            default:
                break;
        }
        //halt($data);
        return $query->where($where);
    }

    //入院科室
    public function searchInhospitalDeptAttr($query, $value, $data)
    {
        return $query->where('inList.inhospitalDept', "=", ['$regex' => '^' . trim($value)]);

    }

    //入院病区
    public function searchInhospitalWardAttr($query, $value, $data)
    {

        return $query->where('inList.inhospitalWard', "=", ['$regex' => '^' . trim($value)]);
    }

    //=========================================================================================================================
    /**
     * 按条件查询患者
     */

    //病案号
    public function searchMedicalRecordsNoAttr($query, $value, $data)
    {
        preg_match_all("/[A-Z]?\d+/", $value,$result);
        if(!empty($result)){
            $medical = $result[0];
        }
        //限制病案号个数不能大于5000
        if (count($medical) > 5000) {
            throw new FailedException("病案号个数不能大于5000");
        }

        return $query->where([['medicalRecordsNo', 'in', $medical]]);
    }

    //入院年龄最小
    public function searchStartageAttr($query, $value, $data)
    {
        return $query->where('inage', '>=', $value);
    }

    //入院年龄最大
    public function searchEndageAttr($query, $value, $data)
    {
        return $query->where('inage', '<=', $value);
    }

    //性别
    public function searchSexAttr($query, $value, $data)
    {
        $sex = config('dictionary.sex');
        return $query->where('sex', $sex[$value]);
    }

    //入院日期
    public function searchInDateAttr($query, $value, $data)
    {

        $where = [];
        if (!empty($value[0]) || !empty($value[1])) {
            if (((isset($value[0]) && !empty($value[0])) && (isset($value[1]) && !empty($value[1]))) && $value[0] == $value[1]) {

                $where[] = ['calc_date_node.inhospitalDateArr', '=', date("Y-m-d", strtotime($value[0]))];

            }else{
                if (isset($value[0]) && !empty($value[0])) {

                    $where[] = ['calc_date_node.inhospitalDateArr', '>=', date("Y-m-d", strtotime($value[0]))];
                }
                if (isset($value[1]) && !empty($value[1])) {

                    $where[] = ['calc_date_node.inhospitalDateArr', '<=', date("Y-m-d", strtotime($value[1]))];
                }
            }
        }
        return $query->where($where);
    }

    //门诊日期
    public function searchMzDateAttr($query, $value, $data)
    {
        $where = [];
        if (!empty($value[0]) || !empty($value[1])) {
            if (((isset($value[0]) && !empty($value[0])) && (isset($value[1]) && !empty($value[1]))) && $value[0] == $value[1]) {

                $where[] = ['calc_date_node.visit_time_arr', '=', date("Y-m-d", strtotime($value[0]))];

            }else{
                if (isset($value[0]) && !empty($value[0])) {

                    $where[] = ['calc_date_node.visit_time_arr', '>=', date("Y-m-d", strtotime($value[0]))];
                }
                if (isset($value[1]) && !empty($value[1])) {

                    $where[] = ['calc_date_node.visit_time_arr', '<=', date("Y-m-d", strtotime($value[1]))];
                }
            }
        }
        return $query->where($where);
    }

    //出院日期
    public function searchOutDateAttr($query, $value, $data)
    {
        $where = [];
        if (!empty($value[0]) || !empty($value[1])) {
            if (((isset($value[0]) && !empty($value[0])) && (isset($value[1]) && !empty($value[1]))) && $value[0] == $value[1]) {

                $where[] = ['calc_date_node.outhospitalDateArr.outhospital_date', '=', date("Y-m-d", strtotime($value[0]))];

            }else{
                if (isset($value[0]) && !empty($value[0])) {

                    $where[] = ['calc_date_node.outhospitalDateArr.outhospital_date', '>=', date("Y-m-d", strtotime($value[0]))];
                }
                if (isset($value[1]) && !empty($value[1])) {

                    $where[] = ['calc_date_node.outhospitalDateArr.outhospital_date', '<=', date("Y-m-d", strtotime($value[1]))];
                }
            }
        }
        return $query->where($where);
    }

    //出院病区/科室
    public function searchOutDeptWardAttr($query, $value, $data)
    {
        return $query->whereOr('hoList.outhospitalDeptCode', "=", ['$regex' => '^' . trim($value)])->whereOr('hoList.outhospitalWard', "=", ['$regex' => '^' . trim($value)]);
    }

    //入院病区/科室
    public function searchInDeptWardAttr($query, $value, $data)
    {
        return $query->whereOr('inList.inhospitalDept', "=", ['$regex' => '^' . trim($value)])->whereOr('inList.inhospitalWard', "=", ['$regex' => '^' . trim($value)]);
    }

    //=========================================================================================================================
    //宣教中心列表筛选

    //患者姓名
    public function searchEdNameAttr($query, $value, $data)
    {
        return $query->where('name', '=', ['$regex' => '^' . trim($value)]);
    }

    //病案号
    public function searchEdInhospitalNoAttr($query, $value, $data)
    {
        return $query->where('inList.inhospitalNo', $value);
    }

    //==========================================================================================
    //医生端筛选

    //患者姓名
    public function searchYsdNameAttr($query, $value, $data)
    {
        return $query->where('name', '=', ['$regex' => '^' . trim($value)]);
    }

    //住院号
    public function searchYsdInhospitalNoAttr($query, $value, $data)
    {
        return $query->where('inList.inhospitalNo', $value);
    }

    //门诊日期
    public function searchYsdVisitTimeAttr($query, $value, $data)
    {
        $where = [];
        if (isset($value[0]) && !empty($value[0])) {

            $where[] = ['outList.visitTime', '>=', date("Y-m-d", strtotime($value[0]))];
        }

        if (isset($value[1]) && !empty($value[1])) {

            $where[] = ['outList.visitTime', '<=', date("Y-m-d", strtotime($value[1]))];
        }
        return $query->where($where);
    }

    //医生工号
    // public function searchDoctorCodeAttr($query, $value, $data)
    // {
    //     return $query->whereOr('outList.attendingDoctorId', $value)
    //         ->whereOr('inList.inchargeDoctorNo', $value)
    //         ->whereOr('hoList.inchargeDoctorNo', $value);
    // }

    //关注
    public function searchAttentionAttr($query, $value, $data)
    {
        $where = [];
        if ((int)$value === 1) {
            $userInfo = request()->user();
            $pids = (new CaseModel())->where('attention', $userInfo['id'])->column('pid');
            $where[] = ['id', 'in', $pids];
        }
        return $query->where($where);
    }

    //死亡状态
    public function searchLiveStatusAttr($query, $value, $data)
    {
        $where = [];
        if ($value <> 2) {
            $where[] = ['liveStatus', '=', (string)$value];
        }
        return $query->where($where);
    }

    //死亡时间
    public function searchDeathDateAttr($query, $value, $data)
    {
        $where = [];
        if (isset($value[0]) && !empty($value[0])) {
            $where[] = ['death.deathDate', '>=', (string)$value[0]];
        }

        if (isset($value[1]) && !empty($value[1])) {
            $where[] = ['death.deathDate', '<=', (string)$value[1]];
        }
        return $query->where($where);
    }

    //死亡原因
    public function searchCauseOfDeathAttr($query, $value, $data)
    {
        return $query->where('death.causeOfDeath', $value);
    }

    public function searchBzAttr($query, $value, $data)
    {
        $where = [];
        if (!empty($value)) {
            $where[] = ["bz.bingzhongArr.bingzhong_id", "in", $value];
        }
        return $query->where($where);
    }

    //是否在院
    public function searchIsInHospitalAttr($query, $value, $data)
    {
        return $query->where('is_in_hospital', (int)$value);
    }

    /**
     * @param $value
     * @return mixed|string
     */
    public function getPresentTelphoneAttr($value, $data)
    {

        if (!empty($value)) {
            //判断是不是手机号
            if ($value[0] === "1" && mb_strlen($value) === 11) {
                return $value;
            }
            $value = str_replace("-", "", $value);
            return mb_substr($value, 0, 4) . "-" . mb_substr($value, 4);
        }
        return "";

    }

    //确诊日期
    public function searchFirstTreatDatetimeAttr($query, $value, $data)
    {
        $where = [];
        if (isset($value[0]) && !empty($value[0])) {

            $where[] = ['first_treat_datetime', '>=', date("Y-m-d", strtotime($value[0]))];
        }

        if (isset($value[1]) && !empty($value[1])) {

            $where[] = ['first_treat_datetime', '<=', date("Y-m-d", strtotime($value[1]))];
        }
        return $query->where($where);
    }

    //确诊年龄
    public function searchFirstTreatAgeAttr($query, $value, $data)
    {
        $where = [];
        if (isset($value[0]) && !empty($value[0])) {
            $where[] = ['first_treat_age', '>=', (int)$value[0]];
        }

        if (isset($value[1]) && !empty($value[1])) {
            $where[] = ['first_treat_age', '<=', (int)$value[1]];
        }
        return $query->where($where);
    }

    //随访员
    public function searchFollowStaffAttr($query, $value, $data)
    {
        return $query->where('follow_history.follow_staff.user_id', (int)$value);
    }

    //随访结果
    public function searchFollowResultAttr($query, $value, $data)
    {
        parse_str($value, $output);
        $output = array_map('intval', $output);
        return $query->whereIn('follow_history.follow_result.result', $output);
    }

    //随访时间
    public function searchFollowTimeAttr($query, $value, $data)
    {
        $where = [];
        if (isset($value[0]) && !empty($value[0])) {
            $where[] = ['follow_history.follow_time.pushtime', '>=', (string)$value[0]];
        }

        if (isset($value[1]) && !empty($value[1])) {
            $where[] = ['follow_history.follow_time.pushtime', '<=', (string)$value[1]];
        }
        return $query->where($where);
    }

    //出生日期
    public function searchBirthdateAttr($query, $value, $data)
    {
        $where = [];
        if (isset($value[0]) && !empty($value[0])) {
            $where[] = ['birthdate', '>=', (string)$value[0]];
        }

        if (isset($value[1]) && !empty($value[1])) {
            $where[] = ['birthdate', '<=', (string)$value[1]];
        }
        return $query->where($where);
    }

    //失访原因
    public function searchLostReasonsAttr($query, $value, $data)
    {
        return $query->where('lost_access_result_code', (int)$value);
    }

    //失访后的更新状态
    public function searchLostUpStatusAttr($query, $value, $data)
    {
        $where = [];
        switch ($value) {
            case 1:
                $where[] = ['lost_access_visit_status', '=', 1];
                break;
            case 2:
                $where[] = ['lost_access_phone_status', '=', 1];
                break;
            case 3:
                $where[] = ['lost_access_visit_status', '=', 1];
                $where[] = ['lost_access_phone_status', '=', 1];
                break;
            default:
                break;
        }
        return $query->where($where);
    }
    //患者登记号
    public function searchRegistrationNoAttr($query, $value, $data)
    {
        return $query->where('patient_id', (string)$value);
    }

    //分娩开始日期
//    public function searchBirthdateAttr($query, $value, $data)
//    {
//        $where = [];
//        if (isset($value[0]) && !empty($value[0])) {
//            if ($data['type'] == 2) {
//                $where[] = ['inList.time_of_birth', '>=', $value[0]];
//            }elseif ($data['type'] == 3){
//                $where[] = ['hoList.time_of_birth', '>=', $value[0]];
//            }
//        }
//
//        if (isset($value[1]) && !empty($value[1])) {
//            if ($data['type'] == 2) {
//                $where[] = ['inList.time_of_birth', '<=', $value[1]];
//            }elseif ($data['type'] == 3){
//                $where[] = ['hoList.time_of_birth', '<=', $value[1]];
//            }
//        }
//        return $query->where($where);
//    }

}